package org.Shiikong_Memory.SakuraBlockFrame.BasisTool;

import lombok.NonNull;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * ConfigTool 类用于管理和加载插件的配置文件。
 * 该类提供了加载和保存配置文件的方法，以及创建默认配置文件的功能。
 * 该类使用了 Lombok 的 @NonNull 注解，以确保传递给方法的参数不为 null。
 *
 * @author Shiikong_Memory
 * @version 1.0
 */
public class ConfigTool {
    // 静态日志记录器，用于记录日志信息
    private static Logger logger;
    // JavaPlugin 类型的插件实例，用于访问插件的资源和数据文件夹
    private final JavaPlugin plugin;
    // 一个嵌套的 Map，用于存储按组分类的配置文件
    private final Map<String, Map<String, FileConfiguration>> groupedConfigs;

    /**
     * 构造函数，初始化配置工具类。
     *
     * @param plugin JavaPlugin 类型的插件实例
     */
    public ConfigTool(@NonNull JavaPlugin plugin) {
        this.plugin = plugin;
        // 获取插件的日志记录器
        logger = plugin.getLogger();
        // 初始化 groupedConfigs 为一个新的 HashMap
        this.groupedConfigs = new HashMap<>();
        // 调用 loadConfigs() 方法加载配置文件
        loadConfigs();
    }

    /**
     * 创建默认配置文件。
     *
     * @param group            配置文件所在的组
     * @param configFileName   配置文件的名称
     * @param defaultResourceName 默认资源文件的名称
     */
    public void createDefaultConfig(String group, @NonNull String configFileName, @NonNull String defaultResourceName) {
        group = group==null?"":group;
        // 创建组文件夹对象
        File groupFolder = new File(plugin.getDataFolder(), group);
        // 检查组文件夹是否存在，如果不存在则创建
        if (!groupFolder.exists()) {
            groupFolder.mkdirs();
        }
        // 创建配置文件对象
        File configFile = new File(groupFolder, configFileName);
        // 检查配置文件是否存在，如果不存在则创建默认配置
        if (!configFile.exists()) {
            try (
                    // 从插件资源中获取默认资源的输入流
                    InputStream in = plugin.getResource(defaultResourceName);
                    // 创建输入流读取器
                    InputStreamReader reader = new InputStreamReader(in)
            ) {
                // 从输入流读取器加载默认配置
                FileConfiguration defaultConfig = YamlConfiguration.loadConfiguration(reader);
                // 保存默认配置到文件
                defaultConfig.save(configFile);
            } catch (IOException e) {
                // 记录创建默认配置失败的错误日志
                plugin.getLogger().severe("创建默认配置失败：" + group + "/" + configFileName);
                // 打印异常堆栈信息
                e.printStackTrace();
            }
        }
    }

    /**
     * 加载所有配置文件。
     */
    private void loadConfigs() {
        // 获取插件的数据文件夹
        File dataFolder = plugin.getDataFolder();
        // 检查数据文件夹是否存在，如果不存在则创建
        if (!dataFolder.exists()) {
            dataFolder.mkdirs();
        }
        // 调用 loadConfigsRecursively 方法递归加载配置文件
        loadConfigsRecursively(dataFolder, "");
    }

    /**
     * 递归加载指定目录下的所有配置文件。
     *
     * @param directory 要加载的目录
     * @param group     当前的组名
     */
    private void loadConfigsRecursively(@NonNull File directory, String group) {
        group = group==null?"":group;
        // 获取目录下的所有文件和文件夹
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 如果是目录，则递归调用 loadConfigsRecursively 方法
                    String newGroup = group.isEmpty() ? file.getName() : group + "/" + file.getName();
                    loadConfigsRecursively(file, newGroup);
                } else if (file.getName().endsWith(".yml")) {
                    // 如果是 .yml 文件，则加载配置并添加到 groupedConfigs 中
                    String configName = file.getName().replace(".yml", "");
                    FileConfiguration config = YamlConfiguration.loadConfiguration(file);
                    groupedConfigs.computeIfAbsent(group.toLowerCase(), k -> new HashMap<>()).put(configName, config);
                }
            }
        }
    }

    /**
     * 根据组名和配置文件名获取配置文件。
     *
     * @param group      配置文件所在的组
     * @param configName 配置文件的名称
     * @return 配置文件对象，如果不存在则返回 null
     */
    public FileConfiguration getConfig(String group, @NonNull String configName) {
        group = group==null?"":group;
        // 获取指定组的配置文件映射
        Map<String, FileConfiguration> groupConfigs = groupedConfigs.get(group.toLowerCase());
        // 返回指定配置文件，如果不存在则返回 null
        return groupConfigs != null ? groupConfigs.get(configName) : null;
    }

    /**
     * 根据组名获取该组下的所有配置文件。
     *
     * @param group 配置文件所在的组
     * @return 该组下的所有配置文件映射，如果不存在则返回空的 HashMap
     */
    public Map<String, FileConfiguration> getGroupConfigs(String group) {
        group = group==null?"":group;
        // 返回指定组的所有配置文件映射，如果不存在则返回空的 HashMap
        return groupedConfigs.getOrDefault(group.toLowerCase(), new HashMap<>());
    }

    /**
     * 根据组名和配置文件名保存配置文件。
     *
     * @param group      配置文件所在的组
     * @param configName 配置文件的名称
     */
    public void saveConfig(String group, @NonNull String configName) {
        group = group==null?"":group;
        // 获取指定组的配置文件映射
        Map<String, FileConfiguration> groupConfigs = groupedConfigs.get(group);
        if (groupConfigs != null) {
            // 获取指定配置文件
            FileConfiguration config = groupConfigs.get(configName);
            if (config != null) {
                // 构建配置文件的路径
                String filePath = group.isEmpty() ? configName + ".yml" : group.replace("/", File.separator) + File.separator + configName + ".yml";
                // 创建配置文件对象
                File configFile = new File(plugin.getDataFolder(), filePath);
                try {
                    // 保存配置文件
                    config.save(configFile);
                } catch (IOException e) {
                    // 记录保存配置文件失败的错误日志
                    logger.severe("创建默认配置失败：" + group + "/" + configName);
                    // 打印异常堆栈信息
                    e.printStackTrace();
                }
            }
        }
    }
}